package com.atguigu.gmall.activity.receiver;

import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;


@Component
public class SeckillReceiver {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private SeckillGoodsService seckillGoodsService;


    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = MqConst.QUEUE_TASK_1,durable = "true",autoDelete = "false"),
                    exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),key = {MqConst.ROUTING_TASK_1}))
    public void redis(Message message, Channel channel){
        try {
            QueryWrapper<SeckillGoods> wrapper = new QueryWrapper<>();
            wrapper.eq("status","1");
            wrapper.gt("stock_count",0);
            wrapper.eq("DATE_FORMAT(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));

            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(wrapper);
            for (SeckillGoods seckillGoods : seckillGoodsList) {
                //判断当前的缓存key中是否有秒杀商品的SKUID
                Boolean flag = redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).hasKey(seckillGoods.getSkuId().toString());
                if(flag){
                    //表示缓存以放入商品
                    continue;
                }
                redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).put(seckillGoods.getSkuId().toString(),seckillGoods);
                //  将每个商品对应的库存剩余数，放入redis-list 集合中！
                for (Integer i = 0;i<seckillGoods.getStockCount();i++){
                    String key = RedisConst.SECKILL_STOCK_PREFIX+seckillGoods.getSkuId();
                    redisTemplate.opsForList().leftPush(key,seckillGoods.getSkuId().toString());
                }
                redisTemplate.convertAndSend("seckillpush",seckillGoods.getSkuId()+":1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    //监听用户和商品的消息
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = MqConst.QUEUE_SECKILL_USER, durable = "true", autoDelete = "false"), exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_USER), key = {MqConst.ROUTING_SECKILL_USER}))
    public void seckillUser(UserRecode userRecode,Message message,Channel channel){
        try {
            //判断接收过来的数据
            if(userRecode != null){
                seckillGoodsService.seckillOrder(userRecode.getSkuId(),userRecode.getUserId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //手动确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
    //监听秒杀库存信息
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = MqConst.QUEUE_SECKILL_USER, durable = "true", autoDelete = "false"), exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_STOCK), key = {MqConst.ROUTING_SECKILL_USER}))
    public void seckillStock(Long skuId,Message message,Channel channel){

        try {
            if(skuId != null){
                seckillGoodsService.seckillStock(skuId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //消息确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
    //监听删除消息
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = MqConst.QUEUE_TASK_18, durable = "true", autoDelete = "false"), exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK), key = {MqConst.ROUTING_TASK_18}))
    public void deleteRedisData(Message message,Channel channel){
        try {
            QueryWrapper<SeckillGoods> wrapper = new QueryWrapper<>();

            wrapper.eq("status",1);
            wrapper.le("end_time",new Date());

            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(wrapper);
            for (SeckillGoods seckillGoods : seckillGoodsList) {
                redisTemplate.delete(RedisConst.SECKILL_STOCK_PREFIX + seckillGoods.getSkuId());
            }
            redisTemplate.delete(RedisConst.SECKILL_GOODS);
            redisTemplate.delete(RedisConst.SECKILL_GOODS);
            redisTemplate.delete(RedisConst.SECKILL_ORDERS_USERS);

            SeckillGoods seckillGoods = new SeckillGoods();
            seckillGoods.setStatus("2");

            seckillGoodsMapper.update(seckillGoods,wrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //手动确认消息
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}
